package com.ebspp.server.replication;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.thrift.TException;
import org.apache.thrift.transport.TTransportException;

import com.ebspp.thrift.DataMsg;
import com.ebspp.thrift.Identity;
import com.ebspp.thrift.ResourceType;

public class ReplicationManager 
{
	private static Map<String, Map<ResourceType, WatchConnection>> waConnMap;

	static
	{
		waConnMap = Collections.synchronizedMap(new HashMap<String, Map<ResourceType, WatchConnection>>());
	}
	
	public synchronized static WatchConnection createWatchConn(String watcher, ResourceType resType, Identity wID)
	{
		
		Map<ResourceType, WatchConnection> resConnMap = waConnMap.get(watcher);
		if(resConnMap == null)
		{
			resConnMap = Collections.synchronizedMap(new HashMap<ResourceType, WatchConnection>());
			waConnMap.put(watcher, resConnMap);
		}
		WatchConnection waConn = resConnMap.get(resType);
		if(waConn != null)
			return waConn;

		try 
		{
			waConn = new WatchConnection(watcher, resType, wID);
			resConnMap.put(resType, waConn);
			waConn.connect();
		} 
		catch (TTransportException e) {
			// TODO Auto-generated catch block
			System.err.println("Cannot create watch connection to watcher" + watcher);
			if(resConnMap.size() == 0)
				waConnMap.remove(watcher);
			e.printStackTrace();
			return null;
		}
		
		return waConn;
	}
	
	public synchronized static boolean closeWatchConn(String watcher, ResourceType resType)
	{
		Map<ResourceType, WatchConnection> resConnMap = waConnMap.get(watcher);
		if(resConnMap == null)
			return true;
		
		WatchConnection waConn = resConnMap.get(resType);
		if(waConn == null)
			return true;
		
		waConn.close();
		resConnMap.remove(resType);
		if(resConnMap.size() == 0)
			waConnMap.remove(watcher);
		return true;
	}
	
	
	public static boolean notifyWatcher(String watcher, ResourceType resType, List<DataMsg> data)
	{
		Map<ResourceType, WatchConnection> resConnMap = waConnMap.get(watcher);
		if(resConnMap == null)
			return false;
		WatchConnection waConn = resConnMap.get(resType);
		if(waConn == null)
			return false;
		
		try {
			waConn.notify(data);
		} catch (TException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
		return true;
	}
	
}
